<meta charset='utf8' />
<canvas id='canvas' width='256px' height='256px'></canvas>
<script type="text/javascript">
	var Word = function(){
		this.ctx = null;
		this.barriers = null;
		this.barrier = null;
		this.w = null;
		this.h = null;
	};
	Word.prototype.initalize = function(b, c){
		this.barriers = b;
		this.ctx = c.getContext('2d');
		this.w = c.width;
		this.h = c.height;
		this.draw();
	};
	Word.prototype.draw = function(){
		this.ctx.clearRect(0, 0, this.w, this.h);
		this.ctx.beginPath();
		this.ctx.moveTo(this.barriers[0].x, this.barriers[0].y);
		for(var i = 1; i < this.barriers.length; i++){
			this.ctx.lineTo(this.barriers[i].x, this.barriers[i].y);
		}
		this.ctx.stroke();
		this.ctx.closePath();
	};
	Word.prototype.barrierPlane = function(particle){
		var len = this.barriers.length - 1;
		var v2 = particle.move;
		for(var i = 0; i < len; i++){
			var v1 = this.barriers[i + 1].substract(this.barriers[i]);
			var v3 = particle.site.substract(this.barriers[i]);
			if(this.crashTest(v1, v2, v3)){
				this.barrier = v1;
				// particle.move = this.reflect(v1, v2);
				return true;
			}
		}
		return false;
	};
	Word.prototype.crashTest = function(v1, v2, v3){
		//v1 - v2 = v3;
		var d = v1.x * (-v2.y) - v1.y * (-v2.x);
		if(d == 0){
			return false;
		}
		var d1 = v3.x * (-v2.y) - v3.y * (-v2.x);
		var d2 = v1.x * v3.y - v1.y * v3.x;
		var s = d1 / d;
		var t = d2 / d;
		if(s < 0 || s > 1 || t < 0 || t > 1){
			return false;
		}
		return true;
	};
	Word.prototype.reflect = function(p){
		var normal = new Vector2(-this.barrier.y, this.barrier.x);
		normal.unitization();
		var v = p.move;
		v.negate();
		var n = normal.multiply(v.negate().dot(normal));
		v.add(n.multiply(2));
		// p.move = v;
	};
	var Vector2 = function(x, y){
		this.x = x;
		this.y = y;
	};
	Vector2.prototype.add = function(v){
		this.x += v.x;
		this.y += v.y;
	};
	Vector2.prototype.multiply = function(r){
		return new Vector2(this.x * r, this.y * r);
	};
	Vector2.prototype.substract = function(v){
		return new Vector2(this.x - v.x, this.y - v.y);
	};
	Vector2.prototype.negate = function(){
		return new Vector2(-this.x, -this.y);
	};
	Vector2.prototype.dot = function(v){
		return this.x * v.x + this.y * v.y;
	};
	Vector2.prototype.unitization = function(){
		var len = Math.sqrt(this.dot(this));
		this.x /= len;
		this.y /= len;
	};
	var word = new Word();
	var barrier = [];
	barrier.push(new Vector2(32, 32));
	barrier.push(new Vector2(32, 128));
	barrier.push(new Vector2(128, 200));
	barrier.push(new Vector2(120, 80));
	barrier.push(new Vector2(210, 80));
	barrier.push(new Vector2(110, 10));
	barrier.push(new Vector2(32, 32));
	word.initalize(barrier, canvas);
	var Particle = function(s, m){
		this.site = s;
		this.move = m;
	};
	function randomSpeed(){
		var x = Math.round(Math.random() * 4 - 2);
		var y = Math.round(Math.random() * 4 - 2);
		return new Vector2(x, y);
	}
	var p = new Particle(new Vector2(96, 96), randomSpeed());
	function draw(){
		word.draw();
		if(word.barrierPlane(p)){
			word.reflect(p);
		}
		p.site.add(p.move);
		word.ctx.beginPath();
		word.ctx.arc(p.site.x, p.site.y, 2, Math.PI * 2, false);
		word.ctx.fill();
		word.ctx.closePath();
	}
	// draw();
	setInterval(draw, 33);
</script>